@page "/admin/editor/{Slug?}/"
@inject HttpClient _http
@inject IStringLocalizer<Resource> _localizer
@inject IJSRuntime _jsruntime
@inject IToaster _toaster
@inject NavigationManager _navigation
@inject BlogStateProvider _stateprovider
@implements IDisposable

<PageTitle Title="@_localizer["new-post"]" />

@if (Post != null)
{
<div class="bfeditor">
    <div class="bfeditor-header">
        <img class="bfeditor-cover" src="@Post.Cover" alt="@_localizer["cover"]" id="postCover">
        <div class="bfeditor-actions">
            <div class="container d-flex">
                @if (Post.Id == 0)
                {
                    <button type="button" class="btn btn-blogifier me-3 px-4" @onclick="() => Publish()">@_localizer["publish"]</button>
                    <button type="button" class="btn btn-default me-auto" @onclick="() => Save()" @onclick:preventDefault>@_localizer["save"]</button>
                }
                else
                {
                    if (Post.Published > DateTime.MinValue)
                    {
                        <button type="button" class="btn btn-blogifier me-3 px-4" @onclick="() => Save()">@_localizer["save"]</button>
                        <button type="button" class="btn btn-default me-auto" @onclick="() => Unpublish()" @onclick:preventDefault>@_localizer["unpublish"]</button>
                        <button class="btn btn-link text-white me-1" @onclick="(() => Remove(Post.Id))">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
                                <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
                                <path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
                            </svg>
                            <span class="ms-2 d-none d-lg-inline">@_localizer["delete"]</span>
                        </button>
                        <a href="posts/@Post.Slug" class="btn btn-link text-white" target="_blank">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-up-right" viewBox="0 0 16 16">
                                <path fill-rule="evenodd" d="M14 2.5a.5.5 0 0 0-.5-.5h-6a.5.5 0 0 0 0 1h4.793L2.146 13.146a.5.5 0 0 0 .708.708L13 3.707V8.5a.5.5 0 0 0 1 0v-6z" />
                            </svg>
                            <span class="ms-2 d-none d-lg-inline">@_localizer["view"]</span>
                        </a>
                    }
                    else
                    {
                        <button type="button" class="btn btn-blogifier me-3 px-4" @onclick="() => Publish()">@_localizer["publish"]</button>
                        <button type="button" class="btn btn-default me-auto" @onclick="() => Save()" @onclick:preventDefault>@_localizer["save"]</button>
                        <button class="btn  text-white btn-link" @onclick="(() => Remove(Post.Id))">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
                                <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
                                <path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
                            </svg>
                            <span class="ms-2 d-none d-lg-inline">@_localizer["delete"]</span>
                        </button>
                    }
                }
            </div>
        </div>
        <div class="bfeditor-header-inner">
            <div class="container">
                <textarea class="bfeditor-header-textarea bfeditor-header-title autosize" @bind="Post.Title" name="title" placeholder="@_localizer["post-title"]" rows="1" autofocus></textarea>
                <textarea class="bfeditor-header-textarea bfeditor-header-desc autosize" @bind="Post.Description" name="description" placeholder="@_localizer["description"]..." rows="1"></textarea>
                <div class="bfeditor-meta d-flex">
                    <div class="dropdown me-3">
                        <a class="bfeditor-meta-link" href="#" id="coverDropdown" data-bs-toggle="dropdown" aria-expanded="false">
                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-image me-1" viewBox="0 0 16 16">
                                <path d="M6.002 5.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>
                                <path d="M2.002 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2h-12zm12 1a1 1 0 0 1 1 1v6.5l-3.777-1.947a.5.5 0 0 0-.577.093l-3.71 3.71-2.66-1.772a.5.5 0 0 0-.63.062L1.002 12V3a1 1 0 0 1 1-1h12z"/>
                            </svg>
                            @_localizer["cover"]
                        </a>
                        <ul class="dropdown-menu" aria-labelledby="coverDropdown">
                            <li>
                                <button class="dropdown-item" onclick="return fileManager.uploadClick('@UploadType.PostCover', @Post.Id);" type="button">@_localizer["change"]</button>
                                <input type="hidden" class="txt-upload" @bind="Post.Cover" name="cover" id="cover" readonly />
                            </li>
                            <li>
                                <button class="dropdown-item" type="button" @onclick="() => ResetCover()">@_localizer["reset"]</button>
                            </li>
                        </ul>
                    </div>
                    <CategoriesComponent Post="Post" @ref="Categories" />
                </div>
            </div>
        </div>
    </div>
    <EditorComponent Content="@Post.Content" Toolbar="fullToolbar" />
</div>
}

<ToasterComponent @ref="Toaster" />

@code
{
   protected Author Author { get; set; }
   protected Post Post { get; set; }
   protected ToasterComponent Toaster;
   protected CategoriesComponent Categories;
   protected string Confirm { get; set; }
   protected string PostTile
   {
       get
       {
           return _stateprovider.PostType == PostType.Post ? _localizer["post-title"] : _localizer["page-title"];
       }
   }

   [Parameter]
#nullable enable
   public string? Slug { get; set; }
#nullable disable

   protected override async Task OnInitializedAsync()
   {
       Author = await _http.GetFromJsonAsync<Author>("api/author/getcurrent");
       Confirm = _localizer["confirm-delete"];
       _stateprovider.OnChange += StateHasChanged;
       await Load();
   }

   protected async Task Load()
   {
       Post = NewPost();

       if (!string.IsNullOrEmpty(Slug))
       {
           Post = await _http.GetFromJsonAsync<Post>($"api/post/byslug/{Slug}");
           var headTitle = _localizer["edit"] + " - " + Post.Title;
           await _jsruntime.InvokeVoidAsync("commonJsFunctions.setTitle", headTitle);
       }
   }

   protected async Task SavePost(PostAction postAction)
   {
       Post.Content = await _jsruntime.InvokeAsync<string>("commonJsFunctions.getEditorValue", "");
       Post.PostType = _stateprovider.PostType;

       Post.Cover = await _jsruntime.InvokeAsync<string>("commonJsFunctions.getSrcValue", "postCover");
       Post.Cover = Post.Cover.Replace(_navigation.BaseUri, "");

       if(string.IsNullOrEmpty(Post.Cover))
           Post.Cover = Constants.DefaultCover;

       if (string.IsNullOrEmpty(Post.Description))
           Post.Description = Post.Title;

       if (string.IsNullOrEmpty(Post.Title) || string.IsNullOrEmpty(Post.Content))
       {
           _toaster.Error(_localizer["title-content-required"]);
           return;
       }

       if (postAction == PostAction.Publish)
           Post.Published = DateTime.UtcNow;

       if (postAction == PostAction.Unpublish)
           Post.Published = DateTime.MinValue;

       if (Post.Id == 0)
       {
           Post.Slug = await _http.GetStringAsync($"api/post/getslug/{Post.Title}");
           HttpResponseMessage result = await _http.PostAsJsonAsync<Post>($"api/post/add", Post);

           if(result.IsSuccessStatusCode)
           {
               Post = await _http.GetFromJsonAsync<Post>($"api/post/byslug/{Post.Slug}");
               await _http.PutAsJsonAsync<List<Category>>($"api/category/{Post.Id}", Categories.PostCategories);

               if (postAction == PostAction.Publish)
               {
                   await _http.GetFromJsonAsync<bool>($"api/newsletter/send/{Post.Id}");
               }

               _navigation.NavigateTo($"/admin/editor/{Post.Slug}");
               await Load();
           }

           Toaster.Toast(result);
       }
       else
       {
           Toaster.Toast(await _http.PutAsJsonAsync<Post>($"api/post/update", Post));

           await _http.PutAsJsonAsync<List<Category>>($"api/category/{Post.Id}", Categories.PostCategories);

           await _http.GetFromJsonAsync<bool>($"api/newsletter/send/{Post.Id}");
           await Load();
       }
   }

   protected async Task Save()
   {
       await SavePost(PostAction.Save);
   }

   protected async Task Publish()
   {
       await SavePost(PostAction.Publish);
   }

   protected async Task Unpublish()
   {
       await SavePost(PostAction.Unpublish);
   }

   protected async Task Remove(int id)
   {
       if (await _jsruntime.InvokeAsync<bool>("confirm", Confirm))
       {
           Toaster.Toast(await _http.DeleteAsync($"api/post/{id}"));
           _navigation.NavigateTo($"admin");
       }
   }

   protected async Task ResetCover()
   {
       Post.Cover = Constants.DefaultCover;
       await Save();
   }

   protected async Task RemoveCover()
   {
       Post.Cover = null;
       await Save();
   }

   protected Post NewPost()
   {
       return new Post
       {
           Id = 0,
           Title = "",
           Description = "",
           Content = "",
           AuthorId = Author.Id,
           PostType = PostType.Post,
           Cover = Constants.DefaultCover
       };
   }

   public void Dispose()
   {
       _stateprovider.OnChange -= StateHasChanged;
   }
}
